/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hivInteractions;

import java.io.File;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import units.CellType;
import units.MonkeyType;
import utils.Handle;
import utils.fishersExact.FishersExactTest;

/**
 *
 * @author jamie
 */
public class HivInteractionEnrichment {

    private Handle handle = Handle.getConnectedHandle("monkeys");
    private int minTimePoint = 1;
    private int maxTimePoint = 115;
    private TreeMap<String, List<Integer>> allHivInteractionData;
    private TreeMap<String, List<Integer>> deGenes;
    private int populationSize;
    private File outputFolder_allTP = new File("/Users/jamie/Dropbox/monkeys/hivInteractions/allTimePoints");
    private File outputFolder_individualTP = new File("/Users/jamie/Dropbox/monkeys/hivInteractions/allTimePoints");
    private boolean regulatesOnly = false;
    private boolean upregulatedProteinsOnly = true;

    public HivInteractionEnrichment() {
        populationSize = getPopulationSize();
        allHivInteractionData = getAllHivProtInteractions();
//        testAllTimePoints();
        testIndividualTimePoints();
    }

    private void testAllTimePoints() {
        deGenes = getDEGenes(minTimePoint, maxTimePoint);
        for (MonkeyType mt : MonkeyType.values()) {
            for (CellType ct : CellType.values()) {
                testTimePoints(mt, ct);
            }
        }
    }

    private void testIndividualTimePoints() {

        int[] timePoints = {1, 6, 14, 28, 65, 115, 574, 610};
        for(int tp : timePoints){
            deGenes = getDEGenes(tp, tp);

            for (MonkeyType mt : MonkeyType.values()) {
                for (CellType ct : CellType.values()) {
                    if(deGenes.get(mt.name() + ct.name())!=null){
                        if(deGenes.get(mt.name() + ct.name()).size()>0){
                            testTimePoint(mt, ct, tp);
                        }
                    }
                }
            }
        }
    }

    private void testTimePoints(MonkeyType mt, CellType ct) {
        TreeMap<String, List<Integer>> interactionData = getInteractionData(mt, ct, minTimePoint, maxTimePoint);
        for (String hivInteraction : interactionData.keySet()) {
            double foldEnrichment = getFoldEnrichment(populationSize, allHivInteractionData.get(hivInteraction).size(), deGenes.get(mt.name() + ct.name()).size(), interactionData.get(hivInteraction).size());
            
                FishersExactTest fet = fet(interactionData.get(hivInteraction), allHivInteractionData.get(hivInteraction), deGenes.get(mt.name() + ct.name()));
                System.out.println("all TP\t" + mt.name() + "\t" + ct.name() + "\t" + hivInteraction + "\t" + populationSize + "\t" + allHivInteractionData.get(hivInteraction).size() + "\t" + deGenes.get(mt.name() + ct.name()).size() + "\t" + interactionData.get(hivInteraction).size() + "\t" + foldEnrichment + "\t" + fet.getResult());
            
        }
    }

    private void testTimePoint(MonkeyType mt, CellType ct, int tp) {
        TreeMap<String, List<Integer>> interactionData = getInteractionData(mt, ct, tp, tp);
        for (String hivInteraction : interactionData.keySet()) {
            double foldEnrichment = getFoldEnrichment(populationSize, allHivInteractionData.get(hivInteraction).size(), deGenes.get(mt.name() + ct.name()).size(), interactionData.get(hivInteraction).size());

                FishersExactTest fet = fet(interactionData.get(hivInteraction), allHivInteractionData.get(hivInteraction), deGenes.get(mt.name() + ct.name()));
                System.out.println(tp+"\t" + mt.name() + "\t" + ct.name() + "\t" + hivInteraction + "\t" + populationSize + "\t" + allHivInteractionData.get(hivInteraction).size() + "\t" + deGenes.get(mt.name() + ct.name()).size() + "\t" + interactionData.get(hivInteraction).size() + "\t" + foldEnrichment + "\t" + fet.getResult());

        }
    }

    private FishersExactTest fet(List<Integer> sampleSuccesses, List<Integer> populationSuccesses, List<Integer> sample) {
        FishersExactTest fet = new FishersExactTest(populationSize, populationSuccesses.size(), sample.size(), sampleSuccesses.size());
        return fet;
    }

    private TreeMap<String, List<Integer>> getInteractionData(MonkeyType mt, CellType ct, int minTimePoint, int maxTimePoint) {
        String sql;
        if(!regulatesOnly){
            sql = "select distinct t2.name_1, t2.interaction, t1.gId from differentialexpression t1, hiv_interactions.hiv_interactions t2 where gId_1!='155807' and t1.monkeyType='" + mt.name() + "' and t1.cellType='" + ct.name() + "' and t1.timePoint>=" + minTimePoint + " and t1.timePoint<=" + maxTimePoint + " and t1.pValue<0.1 and t1.gId=t2.gId_2 order by name_1, interaction";
            if(upregulatedProteinsOnly){
                sql = "select distinct t2.name_1, t2.interaction, t1.gId from differentialexpression t1, hiv_interactions.hiv_interactions t2 where gId_1!='155807' and t1.monkeyType='" + mt.name() + "' and t1.cellType='" + ct.name() + "' and t1.timePoint>=" + minTimePoint + " and t1.timePoint<=" + maxTimePoint + " and t1.pValue<0.1 and logExp>0 and t1.gId=t2.gId_2 order by name_1, interaction";
            }
        } else {
            sql = "select distinct t2.name_1, t2.interaction, t1.gId from differentialexpression t1, hiv_interactions.hiv_interactions t2 where interaction regexp 'regulates' and gId_1!='155807' and t1.monkeyType='" + mt.name() + "' and t1.cellType='" + ct.name() + "' and t1.timePoint>=" + minTimePoint + " and t1.timePoint<=" + maxTimePoint + " and t1.pValue<0.1 and t1.gId=t2.gId_2 order by name_1, interaction";
            if(upregulatedProteinsOnly){
                sql = "select distinct t2.name_1, t2.interaction, t1.gId from differentialexpression t1, hiv_interactions.hiv_interactions t2 where interaction regexp 'regulates' and gId_1!='155807' and t1.monkeyType='" + mt.name() + "' and t1.cellType='" + ct.name() + "' and t1.timePoint>=" + minTimePoint + " and t1.timePoint<=" + maxTimePoint + " and t1.pValue<0.1 and logExp>0 and t1.gId=t2.gId_2 order by name_1, interaction";
            }
        }
        ResultSet rs = handle.runSQLquery(sql);
        TreeMap<String, List<Integer>> data = new TreeMap<String, List<Integer>>();
        try {
            while (rs.next()) {
                String hivInteraction = rs.getString("name_1") + "_" + rs.getString("interaction");
                int probeId = rs.getInt("gId");
                if (!data.containsKey(hivInteraction)) {
                    data.put(hivInteraction, new ArrayList<Integer>());
                }
                data.get(hivInteraction).add(probeId);
            }
            rs.close();
        } catch (SQLException ex) {
            Logger.getLogger(HivInteractionEnrichment.class.getName()).log(Level.SEVERE, null, ex);
        }
        return data;
    }

    private TreeMap<String, List<Integer>> getAllHivProtInteractions() {
        String sql;
        if(!regulatesOnly){
            sql = "select distinct name_1, interaction, gId_2 from hiv_interactions.hiv_interactions t1, probeIdLookup t2 where t1.gId_2=t2.gId order by name_1, gId_2";

        } else {
            sql = "select distinct name_1, interaction, gId_2 from hiv_interactions.hiv_interactions t1, probeIdLookup t2 where interaction regexp 'regulates' and t1.gId_2=t2.gId order by name_1, gId_2";
        }
        ResultSet rs = handle.runSQLquery(sql);
        TreeMap<String, List<Integer>> data = new TreeMap<String, List<Integer>>();
        try {
            while (rs.next()) {
                String hivInteraction = rs.getString("name_1") + "_" + rs.getString("interaction");
                int probeId = rs.getInt("gId_2");
                if (!data.containsKey(hivInteraction)) {
                    data.put(hivInteraction, new ArrayList<Integer>());
                }
                data.get(hivInteraction).add(probeId);
            }
            rs.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return data;
    }

    private int getPopulationSize() {
        String sql;
        if(!regulatesOnly){
            sql = "select count(distinct gId_2) from hiv_interactions.hiv_interactions t1, probeIdLookup t2 where  gId_1!='155807' and t1.gId_2=t2.gId";
        } else {
            sql = "select count(distinct gId_2) from hiv_interactions.hiv_interactions t1, probeIdLookup t2 where interaction regexp 'regulates' and gId_1!='155807' and t1.gId_2=t2.gId";
        }
        ResultSet rs = handle.runSQLquery(sql);
        int count = 0;
        try {
            if (rs.next()) {
                count = rs.getInt("count(distinct gId_2)");
            }
            rs.close();
        } catch (SQLException ex) {
            Logger.getLogger(HivInteractionEnrichment.class.getName()).log(Level.SEVERE, null, ex);
        }
        return count;
    }

    private TreeMap<String, List<Integer>> getDEGenes(int minTimePoint, int maxTimePoint) {
        TreeMap<String, List<Integer>> data = new TreeMap<String, List<Integer>>();
        for (MonkeyType mt : MonkeyType.values()) {
            for (CellType ct : CellType.values()) {
                data.put(mt.name() + ct.name(), new ArrayList<Integer>());
                String sql;
                if(!regulatesOnly){
                    sql = "select distinct t1.gId from differentialexpression t1, hiv_interactions.hiv_interactions t2 where t1.gId=t2.gId_2 and t1.monkeyType='" + mt.name() + "' and t1.cellType='" + ct.name() + "' and t1.timePoint>=" + minTimePoint + " and t1.timePoint<=" + maxTimePoint + " and t1.pValue<0.1";
                    if(upregulatedProteinsOnly){
                        sql = "select distinct t1.gId from differentialexpression t1, hiv_interactions.hiv_interactions t2 where t1.gId=t2.gId_2 and t1.monkeyType='" + mt.name() + "' and t1.cellType='" + ct.name() + "' and t1.timePoint>=" + minTimePoint + " and t1.timePoint<=" + maxTimePoint + " and t1.pValue<0.1 and logExp>0";
                    }
                } else {
                    sql = "select distinct t1.gId from differentialexpression t1, hiv_interactions.hiv_interactions t2 where interaction regexp 'regulates' and t1.gId=t2.gId_2 and t1.monkeyType='" + mt.name() + "' and t1.cellType='" + ct.name() + "' and t1.timePoint>=" + minTimePoint + " and t1.timePoint<=" + maxTimePoint + " and t1.pValue<0.1";
                    if(upregulatedProteinsOnly){
                        sql = "select distinct t1.gId from differentialexpression t1, hiv_interactions.hiv_interactions t2 where interaction regexp 'regulates' and t1.gId=t2.gId_2 and t1.monkeyType='" + mt.name() + "' and t1.cellType='" + ct.name() + "' and t1.timePoint>=" + minTimePoint + " and t1.timePoint<=" + maxTimePoint + " and t1.pValue<0.1 and logExp>0";
                    }
                }
                ResultSet rs = handle.runSQLquery(sql);
                try {
                    while (rs.next()) {
                        data.get(mt.name() + ct.name()).add(rs.getInt("t1.gId"));
                    }
                    rs.close();
                } catch (SQLException ex) {
                    Logger.getLogger(HivInteractionEnrichment.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return data;

    }

    private double getFoldEnrichment(int popsize, int popsuc, int samsize, int samsuc) {
        double expected = (popsuc + 0.0) / popsize;
        double actual = (samsuc + 0.0) / samsize;
        if (actual > expected) {
            return actual / expected;
        } else {
            return (expected / actual) * -1.0;
        }
    }


}
